package com.card.server.service.impl;


import com.card.server.config.RedisService;
import com.card.server.constants.HttpConstants;
import com.card.server.constants.JwtConstants;
import com.card.server.domain.R;
import com.card.server.domain.vo.LoginUserVO;
import com.card.server.enums.TimeEnum;
import com.card.server.mapper.ChipMapper;
import com.card.server.mapper.LevelMapper;
import com.card.server.mapper.UserGameLogMapper;
import com.card.server.mapper.UsersMapper;
import com.card.server.model.dto.SignDto;
import com.card.server.model.entity.Chip;
import com.card.server.model.entity.Level;
import com.card.server.model.entity.Users;
import com.card.server.model.ro.UserInfo;
import com.card.server.service.IUserService;
import com.card.server.utils.JsonUtils;
import com.card.server.utils.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl implements IUserService {
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
    private static final String USER_INFO_KEY = "user:info:";
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private LevelMapper levelMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ChipMapper chipMapper;

    @Override
    public R<Users> register(SignDto signDto) {
        // 检查账号是否已存在
//        Users existUser = usersMapper.selectByAccount(signDto.getAccount());
//        if (existUser != null) {
//            return R.fail(400, "账号已存在");
//        }
        // 创建新用户
        Users user = new Users();
        user.setUsername(signDto.getAccount());
        user.setPassword(signDto.getPassword());
        Integer maxId = usersMapper.selectMaxId() + 1;
        user.setAccount(String.format("%06d", maxId));
        user.setId(maxId);
        usersMapper.insert(user);
        // 初始化用户等级
        levelMapper.insert(user.getId());
        // 初始化用户筹码
        chipMapper.insert(user.getId());
        
        return R.ok(user);
    }

    @Override
    public R<String> login(SignDto signDto, HttpServletRequest request) {
        // 验证用户账号密码
        Users user = usersMapper.selectByAccount(signDto.getAccount());
        if (user == null || !user.getPassword().equals(signDto.getPassword())) {
            return R.fail(400, "账号或密码错误");
        }

        // 生成 token
        LoginUserVO loginUser = new LoginUserVO();
        loginUser.setUserId(user.getId());
        loginUser.setUsername(user.getUsername());
        loginUser.setAvatar(user.getAvatarUrl());

        String token = JwtUtils.createToken(loginUser);
        // 缓存用户信息
        cacheUserInfo(user,token);
        request.setAttribute(HttpConstants.USER_ID, user.getId());
        return R.ok(token);
    }

    @Override
    public R<Void> logout(Integer userId) {
        // 清除所有用户相关缓存
        clearUserCache(userId);
        return R.ok();
    }

    @Override
    public R<UserInfo> get(Long userId) {
        UserInfo userInfo = null;
        String userInfoKey = USER_INFO_KEY + userId + ":";
        if (redisService.hasKey(userInfoKey)) {
            //从缓存中获取用户信息
            String userJson = redisService.getCacheObject(userInfoKey, String.class);
            if (userJson != null) {
                Map<String, Object> userData = JsonUtils.parseObject(userJson, Map.class);
                userInfo = new UserInfo();
                userInfo.setId(Integer.valueOf(userData.get("id").toString()) );
                userInfo.setUsername(userData.get("username").toString() );
                userInfo.setAvatar(userData.get("avatar").toString());
                userInfo.setToken(userData.get("token").toString());
                userInfo.setAccount(userData.get("account").toString());
                userInfo.setLevel(Integer.valueOf(userData.get("level").toString()));
                userInfo.setExp(Integer.valueOf(userData.get("exp").toString()));
                userInfo.setChip(Integer.valueOf(userData.get("chip").toString()));
            }
        }
        if (userInfo == null){
            // 从数据库中获取用户信息
            userInfo = new UserInfo();
            Users user = usersMapper.queryById(userId);
            Level level = levelMapper.queryById(userId);
            Chip chip = chipMapper.queryById(userId);
            userInfo.setId(user.getId());
            userInfo.setUsername(user.getUsername());
            userInfo.setAccount(user.getAccount());
            userInfo.setAvatar(user.getAvatarUrl());
            userInfo.setLevel(level.getLevel());
            userInfo.setExp(level.getExp());
            userInfo.setChip(chip.getChip());
        }
        return R.ok(userInfo);
    }


    private void cacheUserInfo(Users user,String token) {
        Map<String, Object> userInfo = new HashMap<>();
        Level level = levelMapper.queryById(Long.valueOf(user.getId()));
        Chip chip = chipMapper.queryById(Long.valueOf(user.getId()));
        userInfo.put("id", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("account", user.getAccount());
        userInfo.put("level", level.getLevel());
        userInfo.put("exp", level.getExp());
        userInfo.put("chip", chip.getChip());
        userInfo.put("avatar", user.getAvatarUrl());
        userInfo.put("token", token);
        
        String userInfoKey = USER_INFO_KEY + user.getId() + ":";
        String userJson = JsonUtils.writeValueAsString(userInfo);
        redisService.setCacheObject(userInfoKey, userJson, TimeEnum.ONE_DAY);
        log.info("用户 {} 基本信息已缓存", user.getUsername());
    }


    private void clearUserCache(Integer userId) {
        // 清除所有用户相关的缓存
        String userInfoKey = USER_INFO_KEY + userId + ":";
        redisService.deleteObject(userInfoKey);
        log.info("用户 ID: {} 的所有缓存已清除", userId);
    }
}
